package com.siao.mvc.core
{
	import com.siao.data.ArrayList;
	
	import flash.utils.getQualifiedClassName;
	
	/**
	 * 树形节点
	 * @author SiaoLeon
	 */
	public class Node implements INode
	{
		// -------------------------------------------------------------------------------------------------------- 静态常量
		
		// -------------------------------------------------------------------------------------------------------- 静态变量
		
		// -------------------------------------------------------------------------------------------------------- 静态方法
		
		// -------------------------------------------------------------------------------------------------------- 静态函数
		
		// -------------------------------------------------------------------------------------------------------- 属性
		
		protected var _parent:INode;
		
		public function get parent():INode
		{
			return this._parent;
		}
		
		public function set parent(node:INode):void
		{
			this._parent = node;
			
			if (this._parent != null && !this._parent.contains(this))
			{
				this._parent.add(this);
			}
		}
		
		private var _childs:ArrayList;
		
		public function get childs():ArrayList
		{
			return this._childs.concat();
		}
		
		public function get path():Array
		{
			var path:Array = new Array();
			var node:INode = this;
			
			while (node != null)
			{
				path.unshift(node);
				node = node.parent;
			}
			
			return path;
		}
		
		// -------------------------------------------------------------------------------------------------------- 变量
		
		// -------------------------------------------------------------------------------------------------------- 构造
		
		/**
		 * 构造函数
		 */
		public function Node()
		{
			this._childs = new ArrayList();
		}
		
		// -------------------------------------------------------------------------------------------------------- 方法
		
		public function add(node:INode):void
		{
			if (!this.contains(node))
			{
				this._childs.add(node);
			}
			
			node.parent = this;
		}
		
		public function remove(node:INode):void
		{
			this._childs.remove(node);
		}
		
		public function clear():void
		{
			for (var i:int = 0; i < this._childs.length; i++)
			{
				(this._childs.element(i) as INode).parent = null;
			}
			
			this._childs.clear();
		}
		
		public function contains(node:INode):Boolean
		{
			return this._childs.contains(node);
		}
		
		public function getParent(node:INode):INode
		{
			var i:int = 0;
			
			if (node == this)
			{
				return this;
			}
			
			while (this.path[i] == node.path[i])
			{
				i++;
			}
			
			return (i > 0) ? this.path[i - 1] : null;
		}
		
		public function getPath(node:INode):Array
		{
			var sameParent:INode = this.getParent(node);
			
			if (sameParent == null)
			{
				return null;
			}
			
			var thisPath:Array = new Array();
			
			var thisParent:INode = this;
			
			while (thisParent != sameParent)
			{
				thisPath.push(thisParent);
				thisParent = thisParent.parent;
			}
			
			var otherPath:Array = new Array();
			
			var otherParent:INode = node;
			
			while (otherParent != sameParent)
			{
				otherPath.unshift(otherParent);
				otherParent = otherParent.parent;
			}
			
			thisPath.push(sameParent);
			
			return thisPath.concat(otherPath);
		}
		
		public function toString():String
		{
			var path:Array = new Array();
			var node:INode = this;
			
			while (node)
			{
				path.unshift(getQualifiedClassName(node).split("::")[1]);
				node = node.parent;
			}
			
			return path.join("/");
		}
	
		// -------------------------------------------------------------------------------------------------------- 函数
	
	}
}
